-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[libc++] Refactor bitset::{any, all} #128445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
30e237c to
097854d
Compare
097854d to
509e87c
Compare
|
@llvm/pr-subscribers-libcxx Author: Peng Liu (winner245) ChangesThe Full diff: https://github.com/llvm/llvm-project/pull/128445.diff 1 Files Affected:
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index f905b6f274e3f..8d0a5ec67a748 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -224,8 +224,12 @@ protected:
return to_ullong(integral_constant < bool, _Size< sizeof(unsigned long long) * CHAR_BIT>());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT {
+ return std::find(__make_iter(0), __make_iter(_Size), false) == __make_iter(_Size);
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT {
+ return std::find(__make_iter(0), __make_iter(_Size), true) != __make_iter(_Size);
+ }
_LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
private:
@@ -388,40 +392,6 @@ __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
return __r;
}
-template <size_t _N_words, size_t _Size>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<_N_words, _Size>::all() const _NOEXCEPT {
- // do middle whole words
- size_t __n = _Size;
- __const_storage_pointer __p = __first_;
- for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
- if (~*__p)
- return false;
- // do last partial word
- if (__n > 0) {
- __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
- if (~*__p & __m)
- return false;
- }
- return true;
-}
-
-template <size_t _N_words, size_t _Size>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<_N_words, _Size>::any() const _NOEXCEPT {
- // do middle whole words
- size_t __n = _Size;
- __const_storage_pointer __p = __first_;
- for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
- if (*__p)
- return true;
- // do last partial word
- if (__n > 0) {
- __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
- if (*__p & __m)
- return true;
- }
- return false;
-}
-
template <size_t _N_words, size_t _Size>
inline size_t __bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT {
size_t __h = 0;
@@ -713,8 +683,8 @@ public:
_LIBCPP_HIDE_FROM_ABI bool operator!=(const bitset& __rhs) const _NOEXCEPT;
# endif
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool test(size_t __pos) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return __base::all(); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return __base::any(); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool none() const _NOEXCEPT { return !any(); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator<<(size_t __pos) const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator>>(size_t __pos) const _NOEXCEPT;
@@ -901,16 +871,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool bitset<_Size>::test(siz
return (*this)[__pos];
}
-template <size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool bitset<_Size>::all() const _NOEXCEPT {
- return __base::all();
-}
-
-template <size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool bitset<_Size>::any() const _NOEXCEPT {
- return __base::any();
-}
-
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
bitset<_Size>::operator<<(size_t __pos) const _NOEXCEPT {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but can you please confirm that the codegen is the same?
|
In terms of codegen (https://godbolt.org/z/cdEbbTTnY at -O2), I found that the previous implementation generates more efficient assembly as it directly checks the underlying storage. In contrast, my proposed implementation introduces function calls to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requesting changes since this degrades codegen.
669261f to
28fb22d
Compare
|
The new refactoring yields exactly the same code in terms of codegen, as verified on https://godbolt.org/z/xx8hb4sPM. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the refactoring! I have a minor suggestion but LGTM otherwise.
| _LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT; | ||
|
|
||
| private: | ||
| struct __bit_not { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't block this patch on it, however it might be nice to consider a follow-up refactoring.
We have a __bit_not in valarray here: https://github.com/llvm/llvm-project/blob/main/libcxx/include/valarray#L491
We could provide a single __bit_not in https://github.com/llvm/llvm-project/blob/main/libcxx/include/__functional/operations.h#L220 and use it from both valarray and bitset.
28fb22d to
018d34e
Compare
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
018d34e to
255b057
Compare
255b057 to
f26d014
Compare
This patch refactors the
all()andany()methods inbitsetto eliminate redundant code while preserving the performance. Code generation remains unchanged, as verified on Compiler Explorer.